<!DOCTYPE html>
<html>
<head>
<title>Physics Diagram of Reference Frames</title>
</head>
<body>
<canvas id="physicsCanvas" width="650" height="450" style="border:1px solid #ccc;"></canvas>

<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // Helper function to draw an arrow from a start point to an end point
    function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();
        ctx.save();
        ctx.translate(tox, toy);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-headlen, -headlen / 2.5);
        ctx.moveTo(0, 0);
        ctx.lineTo(-headlen, headlen / 2.5);
        ctx.stroke();
        ctx.restore();
    }

    // Helper function to draw an arrowhead at a specific point with a given orientation
    function drawArrowHead(ctx, x, y, angle, headlen = 10) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(-headlen, -headlen / 2.5);
        ctx.moveTo(0, 0);
        ctx.lineTo(-headlen, headlen / 2.5);
        ctx.stroke();
        ctx.restore();
    }

    // --- Drawing Parameters ---
    const originX = 60;
    const originY = 350;
    const U = 120; // Represents R
    const oPrimeX = originX + 1.2 * U; // X-coordinate of O'

    // --- Start Drawing ---
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 1.5;

    // --- S Frame (Stationary) ---
    ctx.font = "italic 20px 'Times New Roman'";
    // x-axis
    drawArrow(ctx, originX - 20, originY, originX + 550, originY);
    ctx.fillText('x', originX + 555, originY + 8);
    // y-axis
    drawArrow(ctx, originX, originY + 40, originX, originY - 300);
    ctx.fillText('y', originX - 7, originY - 305);
    // S Frame Labels
    ctx.font = "24px 'Times New Roman'";
    ctx.fillText('O', originX - 25, originY + 20);
    ctx.font = "20px 'SimSun', '宋体'";
    ctx.fillText('S系', originX + 20, originY - 240);

    // --- S' Frame (Moving) ---
    ctx.font = "italic 20px 'Times New Roman'";
    // y'-axis
    drawArrow(ctx, oPrimeX, originY, oPrimeX, originY - 300);
    ctx.fillText("y'", oPrimeX - 25, originY - 285);
    // x'-axis label (shares line with x-axis)
    ctx.fillText("x'", originX + 555, originY - 20);
    // S' Frame Labels
    ctx.font = "24px 'Times New Roman'";
    ctx.fillText("O'", oPrimeX - 10, originY + 25);
    ctx.font = "20px 'SimSun', '宋体'";
    ctx.fillText("S'系", oPrimeX + 20, originY - 240);

    // --- Circle and Related Elements ---
    const circleCenterX = oPrimeX + U;
    const circleCenterY = originY - U;
    const radius = U;

    // Draw the circle
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.arc(circleCenterX, circleCenterY, radius, 0, 2 * Math.PI);
    ctx.stroke();

    // Draw the center point of the circle
    ctx.fillStyle = '#555';
    ctx.beginPath();
    ctx.arc(circleCenterX, circleCenterY, 5, 0, 2 * Math.PI);
    ctx.fill();

    // Draw dashed lines for coordinates
    ctx.lineWidth = 1;
    ctx.setLineDash([5, 5]);
    // Horizontal line from y'-axis to center
    ctx.beginPath();
    ctx.moveTo(oPrimeX, circleCenterY);
    ctx.lineTo(circleCenterX, circleCenterY);
    ctx.stroke();
    // Vertical line from x'-axis to center
    ctx.beginPath();
    ctx.moveTo(circleCenterX, originY);
    ctx.lineTo(circleCenterX, circleCenterY);
    ctx.stroke();
    // Vertical line from center to the top of the circle
    ctx.beginPath();
    ctx.moveTo(circleCenterX, circleCenterY);
    ctx.lineTo(circleCenterX, circleCenterY - radius);
    ctx.stroke();
    ctx.setLineDash([]); // Reset to solid lines

    // Draw 'R' labels on axes
    ctx.font = "italic 24px 'Times New Roman'";
    ctx.fillStyle = 'black';
    ctx.textAlign = 'center';
    ctx.fillText('R', circleCenterX, originY + 25);
    ctx.textAlign = 'right';
    ctx.fillText('R', oPrimeX - 15, circleCenterY + 8);
    ctx.textAlign = 'start'; // Reset text alignment

    // --- Particles P1 and P2 ---
    const particleRadius = 5;
    const particleY = circleCenterY - radius;
    const particleOffset = 12;

    // Draw particle P1
    ctx.fillStyle = '#555';
    ctx.beginPath();
    ctx.arc(circleCenterX - particleOffset, particleY, particleRadius, 0, 2 * Math.PI);
    ctx.fill();
    ctx.fillStyle = 'black';
    ctx.font = "italic 24px 'Times New Roman'";
    ctx.fillText('P', circleCenterX - particleOffset - 22, particleY + 30);
    ctx.font = "italic 16px 'Times New Roman'";
    ctx.fillText('1', circleCenterX - particleOffset - 10, particleY + 33);

    // Draw particle P2
    ctx.fillStyle = '#555';
    ctx.beginPath();
    ctx.arc(circleCenterX + particleOffset, particleY, particleRadius, 0, 2 * Math.PI);
    ctx.fill();
    ctx.fillStyle = 'black';
    ctx.font = "italic 24px 'Times New Roman'";
    ctx.fillText('P', circleCenterX + particleOffset + 5, particleY + 30);
    ctx.font = "italic 16px 'Times New Roman'";
    ctx.fillText('2', circleCenterX + particleOffset + 17, particleY + 33);

    // --- Particle Velocity Indicator ---
    ctx.lineWidth = 1.5;
    const velArrowY = particleY - 25;
    const velSpan = 90;
    const vel_x_left = circleCenterX - velSpan;
    const vel_x_right = circleCenterX + velSpan;

    // Draw the horizontal line for the velocity indicator
    ctx.beginPath();
    ctx.moveTo(vel_x_left, velArrowY);
    ctx.lineTo(vel_x_right, velArrowY);
    ctx.stroke();

    // Draw the arrowheads at both ends
    drawArrowHead(ctx, vel_x_left, velArrowY, Math.PI);      // Points left
    drawArrowHead(ctx, vel_x_right, velArrowY, 0);          // Points right

    // Add velocity labels (3v and v)
    ctx.font = "italic 22px 'Times New Roman'";
    ctx.textAlign = 'center';
    ctx.fillText('3v', circleCenterX - velSpan / 2, velArrowY - 10);
    ctx.fillText('v', circleCenterX + velSpan / 2, velArrowY - 10);
    ctx.textAlign = 'start';

    // --- Frame Velocity Indicator ---
    const frameVelY = originY + 40;
    const frameVelX_start = circleCenterX + radius + 30;
    const frameVelX_end = frameVelX_start + 80;
    drawArrow(ctx, frameVelX_start, frameVelY, frameVelX_end, frameVelY);
    ctx.font = "italic 22px 'Times New Roman'";
    ctx.textAlign = "center";
    ctx.fillText('v', (frameVelX_start + frameVelX_end) / 2, frameVelY - 8);
    ctx.textAlign = "start"; // Reset alignment
</script>

</body>
</html>